ng911ok.lib.msag module#

Implementation of NG911-MSAG comparisons.

class MSAGComparatorFieldMap#

Bases: object

Base class for spreadsheet field mapping classes.

A subclass should be written to represent each type of MSAG-related spreadsheet. Subclasses should have an attrs field (created using fm_field()) for each spreadsheet column that corresponds to a Next-Generation or Legacy field.

See also

fm_field()

classmethod _get_metadata_entry_dict(key: str) dict[str, Any]#
classmethod get_display_name_list() list[str]#
classmethod get_display_names() dict[str, str]#
classmethod get_dtypes() dict[str, ExtensionDtype]#
classmethod get_input_required() list[bool]#

Returns whether each argument requires an input.

class MSAGComparisonIssue(source_nguid: str | None, source_spreadsheet_row: int | None)#

Bases: object

classmethod issues_to_frame(issues: Sequence[Self]) DataFrame#
to_series() Series#
property as_dict_by_table_field: dict[str, Any]#

Returns a dictionary that maps the table field name (as given in the argument to metadata in attrs.field()) of each attrs attribute to its value.

source_nguid: str | None#

NGUID of the record if it is present in the Next-Generation data, otherwise None.

source_spreadsheet_row: int | None#

MSAG or TN row number of the record if it is present in the spreadsheet, otherwise None.

class MSAGFieldMap(*, add_from: str, add_to: str, parity: str, lgcypredir: str, lgcypretyp: str | None = None, lgcystreet: str, lgcytype: str | None = None, lgcysufdir: str | None = None, msagcomm: str, county: str, state: str, esn: str)#

Bases: MSAGComparatorFieldMap

Field mapping data class for MSAG spreadsheets.

add_from: str#
add_to: str#
county: str#
esn: str#
lgcypredir: str#
lgcypretyp: str | None#
lgcystreet: str#
lgcysufdir: str | None#
lgcytype: str | None#
msagcomm: str#
parity: str#
state: str#
class MSAGIssue(source_nguid, source_spreadsheet_row, side, add_from, add_to, parity, street_name, community, state, esn, esn_same_lr=None, message=None)#

Bases: MSAGComparisonIssue

classmethod from_msag_row(row: Series, *, side: Literal['LEFT', 'RIGHT'] | None | NAType = None, message: Callable[[Self], str] | str | None | NAType = None) Self#

Constructor method to be passed to pandas.DataFrame.apply() with axis=1 to generate instances of this class from a pandas.DataFrame.

_message: str | Callable[[Self], str] | None#
add_from: int | None#
add_to: int | None#
community: str | None#
esn: str | None#
esn_field: NG911Field | None#

Name of the ESN field for the feature/row in question; one of ESN, Esn_L, or Esn_R.

esn_same_lr: bool | None#
message: str#

The message describing the issue.

parity: Parity | None#
relate_string: str#
side: Literal['LEFT', 'RIGHT'] | None#
state: str | None#
street_name: str | None#
class NG911MSAGComparator(workspace: PathLike[str] | str, respect_submit: bool, use_edit_session: bool = False, messenger: GPMessenger | None = None, destination: PathLike[str] | str | None = None, msag_path: Path | None = None, msag_fields: MSAGFieldMap | None = None, tn_path: Path | None = None, tn_fields: TNFieldMap | None = None, **env_kwargs)#

Bases: NG911SessionWithProduct

_compute_coverage(df: DataFrame, group_keys: tuple[str, str, str], add_from: str = 'add_from', add_to: str = 'add_to', parity: str = 'parity', *, coverages: MutableMapping[tuple[str, str, str], RoadRangeCoverage] | None = None) dict[tuple[str, str, str], RoadRangeCoverage]#

Computes road ranges coverages from a data frame. Records with null values for the from-address and/or to-address are dropped.

Parameters:
  • df (pd.DataFrame) – Data frame from which to compute coverage

  • group_keys (MSAGStreetKeyTuple) – Tuple of column names corresponding to street name, MSAG community, and ESN

  • add_from (str) – Name of from-address column, default “add_from”

  • add_to (str) – Name of to-address column, default “add_to”

  • parity (str) – Name of parity column, default “parity”

  • coverages (Optional[MutableMapping[MSAGStreetKeyTuple, RoadRangeCoverage]]) – Optional mapping to update in-place

Returns:

Computed coverage dict, which will be the updated coverages object if it was provided

Return type:

MutableMapping[MSAGStreetKeyTuple, RoadRangeCoverage]

_ensure_destination() None#

Creates the output geodatabase if it doesn’t already exist; otherwise does nothing. Once this method returns, the output geodatabase is sure to exist.

_load_spreadsheet_df(spreadsheet_type: Literal['MSAG', 'TN']) DataFrame#

See msag_df and tn_df.

compute_msag_coverage() dict[tuple[str, str, str], RoadRangeCoverage]#
compute_road_centerline_coverage() dict[tuple[str, str, str], RoadRangeCoverage]#
export_msag_issue_table() Path | None#
export_tn_issue_table() Path | None#
find_missing_address_points()#

Finds address that are present in the TN file but not in ADDRESS_POINT.

find_missing_address_ranges()#

Finds address ranges that are present in the MSAG but not in ROAD_CENTERLINE.

find_missing_msag_entries()#

Finds address ranges that are present in ROAD_CENTERLINE but not in the MSAG.

find_missing_tn_entries()#

Finds addresses that are present in ADDRESS_POINT but not in the TN file.

_abc_impl = <_abc._abc_data object>#
_destination: Path#

Path to the geodatabase to which analysis output will be written.

_enter_timestamp: datetime#

Set to None at initialization, to the current time when __enter__() is called, and back to None when __exit__() is called. Used in initilizing ValidationErrorMessages.

_gdb: Path#

Path to the NG911 geodatabase.

_init_timestamp: datetime.datetime#

Set to the current time at initialization.

_is_active: bool#

Whether the environment settings (including workspace) are in effect.

_issues: list[MSAGIssue]#

List of MSAG issues to report.

_msag_df: pd.DataFrame | None#

Data frame with MSAG spreadsheet data. This is None until _load_msag_df() is called.

_respect_submit: bool#

Whether to use SUBMIT='Y' in where clauses by default.

_temporary_items: list[str]#

Keeps track of temporary feature classes and layers to delete upon __exit__() or __del__() being called.

_tn_df: pd.DataFrame | None#

Data frame with telephone number (TN) spreadsheet data. This is None until _load_tn_df() is called.

_use_edit_session: bool#

Whether to utilize an arcpy.da.Editor instance.

destination_prefix: ClassVar[str] = 'MSAG_Analysis'#
editor: arcpy.da.Editor | DummyEditor#

An instance of arcpy.da.Editor for managing edits when _use_edit_session is True. Otherwise, a DummyEditor instance is created, and calling methods on it will have no effect.

property issues: FrozenList[MSAGIssue | TNIssue]#
messenger: SessionMessenger#

The geoprocessing messenger object typically passed to the execute method of a geoprocessing tool (or an instance of FallbackGPMessenger).

property msag_df: DataFrame#

The first time this property is accessed on an instance, the spreadsheet at msag_path is loaded and stored as a pandas.DataFrame (as _msag_df).

This property returns a copy of that data frame, which has the following columns and dtypes:

Column Name

dtype

add_from

UInt32

add_to

UInt32

parity

string (ODD/EVEN/BOTH)

lgcypredir string

lgcypretyp string

lgcystreet string

lgcytype string

lgcysufdir string

msagcomm string

county string

state string

esn string

$name

string

Note

The above dtypes are pandas extension dtypes.

$name is a column computed in the same way as LgcyFulSt.

msag_fields: MSAGFieldMap | None#

Mapping of standard field roles to MSAG column names.

property msag_issue_table_path: Path#

Path to the MSAG issue table (regardless of whether it currently exists).

property msag_issues: FrozenList[MSAGIssue]#
msag_path: Path | None#

Path to the MSAG spreadsheet.

property tn_df: DataFrame#

The first time this property is accessed on an instance, the spreadsheet at tn_path is loaded and stored as a pd.DataFrame (as _tn_df).

This property returns a copy of that data frame, which has the following columns and dtypes:

Column Name

dtype

addnumber

UInt32

addnumsuf

string

predir

string

street

string

msagcomm

string

county

string

state

string

esn

string

tn_fields: TNFieldMap | None#

Mapping of standard field roles to TN column names.

property tn_issue_table_path: Path#

Path to the TN issue table (regardless of whether it currently exists).

property tn_issues: FrozenList[TNIssue]#
tn_path: Path | None#

Path to the telephone number (TN) spreadsheet.

class TNFieldMap(*, addnumber: str, addnumsuf: str, lgcypredir: str, lgcypretyp: str | None = None, lgcystreet: str, lgcytype: str | None = None, lgcysufdir: str | None = None, msagcomm: str, county: str, state: str, esn: str)#

Bases: MSAGComparatorFieldMap

addnumber: str#
addnumsuf: str#
county: str#
esn: str#
lgcypredir: str#
lgcypretyp: str | None#
lgcystreet: str#
lgcysufdir: str | None#
lgcytype: str | None#
msagcomm: str#
state: str#
class TNIssue(source_nguid, source_spreadsheet_row, full_address, address_number, street_name, community, state, esn, telephone_number, message=None)#

Bases: MSAGComparisonIssue

_message: str | Callable[[Self], str] | None#
address_number: str | None | NAType#
community: str | None | NAType#
esn: str | None | NAType#
full_address: str | None | NAType#
message: str#

The message describing the issue.

relate_string: str#
state: str | None | NAType#
street_name: str | None | NAType#
telephone_number: str | None | NAType#
class _MSAGDataFrameAttributes#

Bases: TypedDict

original_columns: dict[str, str | None]#

Dictionary of the data frame columns as keys and the column names from the spreadsheet (or None, if absent) as their values.

source_path: Path#

Path to the source spreadsheet.

source_type: Literal['MSAG', 'TN']#

Type of the source spreadsheet. One of:

  • MSAG for [M]aster [S]treet [A]ddress [G]uide spreadsheet

  • TN for [T]elephone [N]umber spreadsheet

_validate_and_transform_issue_fields(cls: type, fields: list[Attribute]) list[Attribute]#

Function to be used as the field_transformer argument to attrs.define()/attrs.frozen(). This function checks to ensure that each field with table_field in its metadata also has the dtype key set to a pandas extension dtype. It also sets _na_to_none() as the attrs.Attribute.converter. If a converter is already present, it is added as the first converter in a attrs.converters.pipe().

fm_field(dtype: str, display_name: str, default: Any = NOTHING, **kwargs: Any) _CountingAttr#

Wrapper for attrs.field() for use with subclasses of MSAGComparatorMap.

Naming: field map field

Parameters:
  • dtype (str) – Name of the pandas nullable dtype appropriate for the field being mapped

  • display_name (str) – Text to show in the geoprocessing tool interface describing the field being mapped

  • default (Any) – Default value to pass to attrs.field(); default attrs.NOTHING

  • kwargs – Additional keyword arguments to pass to attrs.field()

Returns:

A result from attrs.field() appropriate for use in a subclass of MSAGComparatorMap

Return type:

attr._make._CountingAttr

MSAGStreetKeyTuple#

Tuple of (<street name>, <MSAG community>, <ESN>). There should never be any overlapping address ranges among road centerlines with these values in common.

alias of tuple[str, str, str]